import kotlinx.serialization.*
import kotlinx.serialization.json.*

@Serializable
data class Project(val name:String, val language:String)

@Serializable
abstract class GrandFather {
    abstract var name:String
}

@Serializable
sealed interface GrandModel<T> {
    var grandName : String
    var children : MutableList<T>
    fun getRoute() : String
}

@Serializable
sealed interface Father {
    abstract var name:String
}

@Serializable
sealed class NewFamily: GrandFather(), GrandModel<NewFamily> {

}

@Serializable
class Son3(override var name: String, override var grandName: String, override var children: MutableList<NewFamily>):
    NewFamily() {
    override fun getRoute(): String {
        TODO("Not yet implemented")
    }
}

@Serializable
class Son1(override var name: String, override var grandName: String, override var children: MutableList<NewFamily>) : NewFamily() {
    val id: Int = name.toInt()
    override fun getRoute(): String {
        TODO("Not yet implemented")
    }
}

@Serializable
class Son2(override var name: String, override var grandName: String, override var children: MutableList<NewFamily>) : NewFamily() {
    val code: String = name
    override fun getRoute(): String {
        TODO("Not yet implemented")
    }
}

@Serializable
data class Family (
    var familyName: String,
    val members: MutableList<Father>
)

fun main() {
//    val data = Project("kotlinx.serialization", "Kotlin")
//    val string = Json.encodeToString(data)
//    println(string)
//
//    val obj = Json.decodeFromString<Project>(string)
//    println(obj)

    /**
    val f = Family("flamelet", mutableListOf())
    f.members.add(Son1("son1", 1))
    f.members.add(Son2("son2", "2"))
    val fStr = Json.encodeToString(f)
    println(fStr)

    val fObj = Json.decodeFromString<Family>(fStr)
    println(fObj)
    fObj.members.forEach { println(it.name) }
    **/

    val f = Son3("1", "2", mutableListOf())
    f.children.add(Son1("2", "1", mutableListOf()))
    f.children.add(Son2("3", "1", mutableListOf()))

    val fStr = Json.encodeToString(f)
    println(fStr)

    val fObj = Json.decodeFromString<Son3>(fStr)
    println(fObj)
}